package com.web_bloks.widget.client;

import java.util.Iterator;
import java.util.Vector;

import com.web_bloks.system.client.Logger;

import com.google.gwt.dom.client.Element;
import com.google.gwt.http.client.Response;
import com.google.gwt.user.client.Event;
import com.google.gwt.user.client.DOM;
import com.google.gwt.user.client.ui.FlexTable;
import com.google.gwt.user.client.ui.ClickListener;
import com.google.gwt.user.client.ui.MouseListener;
import com.google.gwt.user.client.ui.Widget; 
import com.google.gwt.user.client.ui.Image;

/**
 * Rating widget
 * 
 * States:
 * - Locked
 * - Opened
 *   - Displays current rating
 *   - Allows user to set a rating
 *   - Once user rates, either LOCK or stay OPEN
 * 
 * Attributes:
 * - LockAfterRating T/F
 * 
 * @author Jean-Lou Dupont
 * @deprecated
 * 
 * WidgetEx functionality:
 * Attributes:
 * - lockafterrating
 *
 */
public class Rating extends FlexTable
	implements ClickListener, MouseListener, WidgetEx, WidgetCommand {

	final static String thisClass = "com.web_bloks.widget.Rating";
	
	final static String DEFAULT_SRC = "star_n.gif";
	
	final static String STAR_N = "star_n.gif";
	final static String STAR_Y = "star_y.gif";
	
	int rating = 0;
	
	Image i1, i2, i3, i4, i5; 
	
	boolean rated = false;
	
	boolean lockAfterRating = true;
	
	Vector<RatingListener> listeners = new Vector<RatingListener>();
	
	String collectionName = null;
	
	String id = null;
	
	/*****************************************
	 * CONSTRUCTOR 
	 *****************************************/
	public Rating() {
		super();
		setup( null, null );
	}
	public Rating(Element parent, Element source) {
		super();
		setup(parent,source);
	}
	private void setup(Element parent,Element source) {
	
		if (null != source) {
			DOM.insertChild( (com.google.gwt.user.client.Element)source, (com.google.gwt.user.client.Element)this.getElement(), 0);
			//this.setElement(source);
		}
		
		i1 = new Image();
		i2 = new Image();
		i3 = new Image();
		i4 = new Image();
		i5 = new Image();

		this.setWidget(0, 0, i1);
		this.setWidget(0, 1, i2);
		this.setWidget(0, 2, i3);
		this.setWidget(0, 3, i4);
		this.setWidget(0, 4, i5);

		i1.getElement().setId( DOM.createUniqueId() );
		i2.getElement().setId( DOM.createUniqueId() );
		i3.getElement().setId( DOM.createUniqueId() );
		i4.getElement().setId( DOM.createUniqueId() );
		i5.getElement().setId( DOM.createUniqueId() );		
		
		i1.setUrl(STAR_N);
		i2.setUrl(STAR_N);
		i3.setUrl(STAR_N);
		i4.setUrl(STAR_N);
		i5.setUrl(STAR_N);
		
		i1.getElement().setAttribute("name", "1");
		i2.getElement().setAttribute("name", "2");
		i3.getElement().setAttribute("name", "3");
		i4.getElement().setAttribute("name", "4");
		i5.getElement().setAttribute("name", "5");
		
		i1.addClickListener(this);
		i2.addClickListener(this);
		i3.addClickListener(this);
		i4.addClickListener(this);
		i5.addClickListener(this);

		i1.addMouseListener(this);
		i2.addMouseListener(this);
		i3.addMouseListener(this);
		i4.addMouseListener(this);
		i5.addMouseListener(this);
		
		if (null != source) {
			this.initFromDOMElement( parent,  source);
		}

	}
	/*****************************************
	 * WidgetEx 
	 *****************************************/
	public void initFromDOMElement(Element parent, Element source){
		//Logger.logDebug(thisClass+"initFromDOMElement: begin");
		
		Boolean lock;
		String value = null;
		
		try {
			value = source.getAttribute("lockafterrating" );
		}catch(Exception e){
			Logger.logWarn(thisClass+".initFromDOMElement: exception raised");
		}
		
		if ( null != value ) {
			lock = Boolean.valueOf(value);
			this.lockAfterRating = (lock == Boolean.TRUE);
		}		
		String id = source.getPropertyString("id");
		setId(id);

		//Element self = this.getElement();

		//source.setInnerHTML( self.getInnerHTML() );
		//this.setElement( source.getFirstChildElement() );
		
		setEvents(i1);
		setEvents(i2);
		setEvents(i3);
		setEvents(i4);
		setEvents(i5);
	}
	private void setEvents( Widget w ) {
		//Element el = DOM.getElementById( w.getElement().getId() );
		Element el = w.getElement();
		DOM.setEventListener((com.google.gwt.user.client.Element) el, this);
		DOM.sinkEvents((com.google.gwt.user.client.Element)el, Event.ONCLICK | Event.ONMOUSEOVER | Event.ONMOUSEOUT);
	}
	public String getOriginCollection() {
		return this.collectionName;
	}
	public void setOriginCollection(String collectionName) {
		this.collectionName = new String( collectionName );
	}
	public void setId(String id) {
		this.id = new String(id);
	}
	public String getId() {
		return this.id;
	}
	/*****************************************
	 * Listeners 
	 *****************************************/
	public void addRatingListener(RatingListener listener) {
		listeners.add(listener);
	}
	public void removeRatingListener(RatingListener listener) {
		listeners.remove(listener);
	}
	protected void notifyListeners() {
		Iterator<RatingListener> it = this.listeners.iterator();
		while (it.hasNext()) {
			Object o = it.next ();
		    ((RatingListener) o).onRatingChanged( this );
		}
	}
	/*****************************************
	 * API 
	 *****************************************/
	public void setRating(int rating) {
		this.rating = rating;
		setStars(rating);
	}
	public int getRating() {
		return rating;
	}
	public boolean getLockAfterRating() {
		return lockAfterRating;
	}
	public void setLockAfterRating() {
		lockAfterRating = true;
	}
	public void setLockAfterRating(boolean s) {
		lockAfterRating = s;
	}
	/*****************************************
	 * EVENT HANDLERS 
	 *****************************************/
	/**
	 * Used to capture events in cases where
	 * the widget is dynamically added to the DOM.
	 * Must use <code>DOM.setEventListener(el, object)</code>.
	 * 
	 */
	public void onBrowserEvent(Event evt) {
		//Logger.logInfo(thisClass+".onBrowserEvent, type:" + DOM.eventGetType(evt) +", [ONCLICK="+Event.ONCLICK+"]");
		
		Element target = DOM.eventGetTarget(evt);
		
		if (DOM.eventGetType(evt) == Event.ONCLICK) {
			doOnClick( target );
			return;
		}
		if (DOM.eventGetType(evt) == Event.ONMOUSEOVER) {
			doOnMouseEnter( target );
			return;
		}
		if (DOM.eventGetType(evt) == Event.ONMOUSEOUT) {
			doOnMouseLeave( target );
			return;
		}
		
	}
	public void onClick(Widget sender) {
		
		Element el = sender.getElement();

		doOnClick(el);
	}
	
	protected void doOnClick(Element el) {
		//Logger.logInfo(thisClass+".onClick");
		
		if (rated && lockAfterRating)
			return;
		
		int index = extractStarIndex( el );
		setRating(index);
		rated = true;
		
		notifyListeners();
	}
	
	public void onMouseEnter(Widget sender){
		//Logger.logInfo(thisClass+".onMouseEnter: " + DOM.getElementProperty( sender.getElement(), "name" ) );

		Element el = sender.getElement();
		doOnMouseEnter(el);
	}
	
	protected void doOnMouseEnter(Element el) {
		//Logger.logInfo(thisClass+".doOnMouseEnter: " + DOM.getElementProperty( el, "name" ) );
		if (rated && lockAfterRating)
			return;
		
		int index = extractStarIndex( el );
		setStars(index);
	}
	
	public void onMouseLeave(Widget sender){
		//Logger.logInfo(thisClass+".onMouseLeave: " + DOM.getElementProperty( sender.getElement(), "name" ) );

		Element el = sender.getElement();
		doOnMouseLeave(el);
	}
	
	protected void doOnMouseLeave(Element el) {
		//Logger.logInfo(thisClass+".doOnMouseLeave: " + DOM.getElementProperty( el, "name" ) );
		if (rated && lockAfterRating)
			return;
		
		setStars(rating);
	}
	
	public void onMouseDown(Widget sender, int x, int y){
	}
	public void onMouseMove(Widget sender, int x, int y){
	}
	public void onMouseUp(Widget sender, int x, int y){
	}

	/*****************************************
	 * HELPERS 
	 *****************************************/
	protected int extractStarIndex(Element el) {
		
		String id = el.getPropertyString( "name" );
		
		int index = Integer.parseInt(id);
		
		return index;
	}
	
	protected int extractStarIndex(Widget w) {
		
		return extractStarIndex( w.getElement() );
	}
	
	protected void setStars(int rating) {
		//Logger.logDebug(thisClass+".setStars, rating=" + rating);
		
		clearStars();
		switch(rating) {
		case 5:
			i5.setUrl(STAR_Y);
		case 4:
			i4.setUrl(STAR_Y);
		case 3:
			i3.setUrl(STAR_Y);
		case 2:
			i2.setUrl(STAR_Y);
		case 1:
			i1.setUrl(STAR_Y);
			break;
		default:
		}
	}
	
	protected void clearStars() {
		i1.setUrl(STAR_N);
		i2.setUrl(STAR_N);
		i3.setUrl(STAR_N);
		i4.setUrl(STAR_N);
		i5.setUrl(STAR_N);
	}
	/*****************************************
	 * WidgetCommand
	 *****************************************/

	public void executeWidgetCommand( Widget source, String cond, Response response ) {
		Logger.logDebug(thisClass+".executeWidgetCommand: cond["+cond+"]");
	}
}//END
